import threading
import time
from warnings import simplefilter

import redis
import talib as ta

from . import BinanceKlineFactroy
from . import BinanceKlinesTool
from .BinanceKlinesInit import BinanceKlinesInit

simplefilter(action='ignore')
pool = redis.ConnectionPool(host='185.227.152.91', password='hfhdtrDGKGIG', port=6377, db=2, decode_responses=True)
redis = redis.Redis(connection_pool=pool)


class BinanceSignalInitAlpha(BinanceKlinesInit):

    def __init__(self, symbol):
        super().__init__(symbol)
        self.score = 0

    def get_score(self, update=False):
        if not update:
            return self.score

        if len(self.klines_1m) < 300:
            return 0
        if len(self.klines_3m) < 300:
            return 0
        if len(self.klines_5m) < 300:
            return 0
        if len(self.klines_15m) < 300:
            return 0
        if len(self.klines_30m) < 300:
            return 0
        if len(self.klines_1h) < 300:
            return 0
        score = 0
        score_details = ""
        now_macd_1m = self.now_macd_1m()

        divergence_1m = self.divergence_1m
        divergence_3m = self.divergence_3m
        divergence_5m = self.divergence_5m
        divergence_15m = self.divergence_15m
        divergence_30m = self.divergence_30m
        divergence_1h = self.divergence_1h

        last_twist_klines_1m = BinanceKlineFactroy.twist_klines(self.klines_1m)[-1:]
        last_twist_klines_3m = BinanceKlineFactroy.twist_klines(self.klines_3m)[-1:]
        last_twist_klines_5m = BinanceKlineFactroy.twist_klines(self.klines_5m)[-1:]
        last_twist_klines_15m = BinanceKlineFactroy.twist_klines(self.klines_15m)[-1:]
        last_twist_klines_30m = BinanceKlineFactroy.twist_klines(self.klines_30m)[-1:]
        last_twist_klines_1h = BinanceKlineFactroy.twist_klines(self.klines_1h)[-1:]

        # if now_macd_1m > 0:
        #     if divergence_1m == 1 and self.now_price > last_twist_klines_1m["close"].values * 1.003:
        #         redis.set(self.symbol + "_condition_1", 2, ex=60)
        #     if divergence_3m == 1 and self.now_price > last_twist_klines_3m["close"].values[0] * 1.004:
        #         redis.set(self.symbol + "_condition_2", 1, ex=3*60)
        #     if divergence_5m == 1 and self.now_price > last_twist_klines_5m["close"].values[0] * 1.005:
        #         redis.set(self.symbol + "_condition_3", 1, ex=5*60)
        #     if divergence_15m == 1 and self.now_price > last_twist_klines_15m["close"].values[0] * 1.009:
        #         redis.set(self.symbol + "_condition_4", 4, ex=15*60)
        #     if divergence_30m == 1 and self.now_price > last_twist_klines_30m["close"].values[0] * 1.012:
        #         redis.set(self.symbol + "_condition_5", 1, ex=30*60)
        #     if divergence_1h == 1 and self.now_price > last_twist_klines_1h["close"].values[0] * 1.020:
        #         redis.set(self.symbol + "_condition_6", 4, ex=60*60)
        #
        # if now_macd_1m < 0:
        #     if divergence_1m == -1 and self.now_price < last_twist_klines_1m["close"].values[0] * 0.997:
        #         redis.set(self.symbol + "_condition_7", -2, ex=60)
        #     if divergence_3m == -1 and self.now_price < last_twist_klines_3m["close"].values[0] * 0.996:
        #         redis.set(self.symbol + "_condition_8", -1, ex=3*60)
        #     if divergence_5m == -1 and self.now_price < last_twist_klines_5m["close"].values[0] * 0.995:
        #         redis.set(self.symbol + "_condition_9", -1, ex=5*60)
        #     if divergence_15m == -1 and self.now_price < last_twist_klines_15m["close"].values[0] * 0.991:
        #         redis.set(self.symbol + "_condition_10", -4, ex=15*60)
        #     if divergence_30m == -1 and self.now_price < last_twist_klines_30m["close"].values[0] * 0.988:
        #         redis.set(self.symbol + "_condition_11", -1, ex=30*60)
        #     if divergence_1h == -1 and self.now_price < last_twist_klines_1h["close"].values[0] * 0.980:
        #         redis.set(self.symbol + "_condition_12", -4, ex=60*60)
        #
        # for i in range(1, 15):
        #     condition = redis.get(self.symbol + "_condition_" + str(i))
        #     if condition is not None:
        #         score += int(condition)

        score = 0
        condition = ""
        if now_macd_1m > 0:
            if divergence_1m == 1 and self.now_price > last_twist_klines_1m["close"].values[0] * 1.003:
                condition += "1 "
                score += 2
            if divergence_3m == 1 and self.now_price > last_twist_klines_3m["close"].values[0] * 1.004:
                condition += "2 "
                score += 1
            if divergence_5m == 1 and self.now_price > last_twist_klines_5m["close"].values[0] * 1.005:
                condition += "3 "
                score += 1
            if divergence_15m == 1 and self.now_price > last_twist_klines_15m["close"].values[0] * 1.009:
                condition += "4 "
                score += 4
            if divergence_30m == 1 and self.now_price > last_twist_klines_30m["close"].values[0] * 1.012:
                condition += "5 "
                score += 1
            if divergence_1h == 1 and self.now_price > last_twist_klines_1h["close"].values[0] * 1.020:
                condition += "6 "
                score += 4

        if now_macd_1m < 0:
            if divergence_1m == -1 and self.now_price < last_twist_klines_1m["close"].values * 0.997:
                condition += "7 "
                score += -2
            if divergence_3m == -1 and self.now_price < last_twist_klines_3m["close"].values[0] * 0.996:
                condition += "8 "
                score += -1
            if divergence_5m == -1 and self.now_price < last_twist_klines_5m["close"].values[0] * 0.995:
                condition += "9 "
                score += -1
            if divergence_15m == -1 and self.now_price < last_twist_klines_15m["close"].values[0] * 0.991:
                condition += "10 "
                score += -4
            if divergence_30m == -1 and self.now_price < last_twist_klines_30m["close"].values[0] * 0.988:
                condition += "11 "
                score += -1
            if divergence_1h == -1 and self.now_price < last_twist_klines_1h["close"].values[0] * 0.980:
                condition += "12 "
                score += -4

        redis.set(self.symbol + '_condition', condition)
        self.score = score
        return score

    def MA_210_1m(self):
        return float(ta.MA(self.klines_1m['close'][-210:].values, 210)[-1:])

    def now_macd_1m(self):
        return self.klines_1m['MACD'].values[-1]

    def MA_210_15m(self):
        return float(ta.MA(self.klines_15m['close'][-210:].values, 210)[-1:])

    def now_macd_15m(self):
        return self.klines_15m['MACD'].values[-1]

    def _kline_update(self):
        self.score = self.get_score(update=True)
        redis.set(self.symbol + '_now_date', self.now_date)
        redis.set(self.symbol + '_score', self.score)
        redis.set(self.symbol + '_now_price', self.now_price)
        redis.set(self.symbol + '_MA210_1m', self.MA_210_1m())
        redis.set(self.symbol + '_MA210_15m', self.MA_210_15m())
        redis.set(self.symbol + '_now_macd_1m', self.now_macd_1m())
        redis.set(self.symbol + '_now_macd_3m', self.now_macd_3m())
        redis.set(self.symbol + '_now_macd_5m', self.now_macd_1m())
        redis.set(self.symbol + '_now_macd_15m', self.now_macd_15m())
        redis.set(self.symbol + '_now_macd_30m', self.now_macd_30m())
        redis.set(self.symbol + '_now_macd_1h', self.now_macd_1h())
        klines_change_date_1m = self.klines_1m.loc[self.klines_1m['state'] != 0]['date'].values
        klines_change_date_3m = self.klines_3m.loc[self.klines_3m['state'] != 0]['date'].values
        klines_change_date_5m = self.klines_5m.loc[self.klines_5m['state'] != 0]['date'].values
        klines_change_date_15m = self.klines_15m.loc[self.klines_15m['state'] != 0]['date'].values
        klines_change_date_30m = self.klines_30m.loc[self.klines_30m['state'] != 0]['date'].values
        klines_change_date_1h = self.klines_1h.loc[self.klines_1h['state'] != 0]['date'].values

        klines_change_1m = "[" + str(klines_change_date_1m[-3]) + "] => [" + \
                           str(klines_change_date_1m[-2]) + "] => [" + \
                           str(klines_change_date_1m[-1]) + "]"

        klines_change_3m = "[" + str(klines_change_date_3m[-3]) + "] => [" + \
                           str(klines_change_date_3m[-2]) + "] => [" + \
                           str(klines_change_date_3m[-1]) + "]"

        klines_change_5m = "[" + str(klines_change_date_5m[-3]) + "] => [" + \
                           str(klines_change_date_5m[-2]) + "] => [" + \
                           str(klines_change_date_5m[-1]) + "]"

        klines_change_15m = "[" + str(klines_change_date_15m[-3]) + "] => [" + \
                            str(klines_change_date_15m[-2]) + "] => [" + \
                            str(klines_change_date_15m[-1]) + "]"

        klines_change_30m = "[" + str(klines_change_date_30m[-3]) + "] => [" + \
                            str(klines_change_date_30m[-2]) + "] => [" + \
                            str(klines_change_date_30m[-1]) + "]"

        klines_change_1h = "[" + str(klines_change_date_1h[-3]) + "] => [" + \
                           str(klines_change_date_1h[-2]) + "] => [" + \
                           str(klines_change_date_1h[-1]) + "]"

        redis.set(self.symbol + '_klines_change_1m', klines_change_1m)
        redis.set(self.symbol + '_klines_change_3m', klines_change_3m)
        redis.set(self.symbol + '_klines_change_5m', klines_change_5m)
        redis.set(self.symbol + '_klines_change_15m', klines_change_15m)
        redis.set(self.symbol + '_klines_change_30m', klines_change_30m)
        redis.set(self.symbol + '_klines_change_1h', klines_change_1h)
        self._score_update(self.score, self.now_price)

    def _score_update(self, score, now_price):
        pass

    def ws_date_interval(self):
        last_date = str(self.now_date)
        last_date = time.strptime(last_date, "%Y-%m-%d %H:%M:%S")
        last_date = time.mktime(last_date)
        return time.time() - last_date

    def MA_210_1m(self):
        return float(ta.MA(self.klines_1m['close'][-210:].values, 210)[-1:])

    def MA_210_3m(self):
        return float(ta.MA(self.klines_3m['close'][-210:].values, 210)[-1:])

    def MA_210_5m(self):
        return float(ta.MA(self.klines_5m['close'][-210:].values, 210)[-1:])

    def MA_210_15m(self):
        return float(ta.MA(self.klines_15m['close'][-210:].values, 210)[-1:])

    def MA_210_30m(self):
        return float(ta.MA(self.klines_30m['close'][-210:].values, 210)[-1:])

    def MA_210_1h(self):
        return float(ta.MA(self.klines_1h['close'][-210:].values, 210)[-1:])

    def now_macd_1m(self):
        return self.klines_1m['MACD'].values[-1]

    def now_macd_3m(self):
        return self.klines_3m['MACD'].values[-1]

    def now_macd_5m(self):
        return self.klines_5m['MACD'].values[-1]

    def now_macd_15m(self):
        return self.klines_15m['MACD'].values[-1]

    def now_macd_30m(self):
        return self.klines_30m['MACD'].values[-1]

    def now_macd_1h(self):
        return self.klines_1h['MACD'].values[-1]

    # def divergence_1m(self):
    #     divergence_1m = BinanceKlinesTool.divergence(self.klines_1m)
    #     if divergence_1m == -1:
    #         if redis.ttl('ETCUSDT_divergence_1m') < 59:
    #             redis.set(self.symbol + '_divergence_1m', -1, ex=60)
    #             redis.set(self.symbol + '_last_time_bottom_divergence_1m', self.klines_1m['date'].values[-1])
    #         return -1
    #     elif divergence_1m == 1:
    #         if redis.ttl('ETCUSDT_divergence_1m') < 59:
    #             redis.set(self.symbol + '_divergence_1m', 1, ex=60)
    #             redis.set(self.symbol + '_last_time_top_divergence_1m', self.klines_1m['date'].values[-1])
    #         return 1
    #     else:
    #         return redis.get(self.symbol + '_divergence_1m')  # 返回一分钟内背离
    #
    # def divergence_3m(self):
    #     divergence_3m = BinanceKlinesTool.divergence(self.klines_3m)
    #     if divergence_3m == -1:
    #         if redis.ttl('ETCUSDT_divergence_3m') < 59:
    #             redis.set(self.symbol + '_divergence_3m', -1, ex=60)
    #             redis.set(self.symbol + '_last_time_bottom_divergence_3m', self.klines_3m['date'].values[-1])
    #         return -1
    #     elif divergence_3m == 1:
    #         if redis.ttl('ETCUSDT_divergence_3m') < 59:
    #             redis.set(self.symbol + '_divergence_3m', 1, ex=60)
    #             redis.set(self.symbol + '_last_time_top_divergence_3m', self.klines_3m['date'].values[-1])
    #         return 1
    #     else:
    #         return redis.get(self.symbol + '_divergence_3m')  # 返回一分钟内背离
    #
    # def divergence_5m(self):
    #     divergence_5m = BinanceKlinesTool.divergence(self.klines_5m)
    #     if divergence_5m == -1:
    #         if redis.ttl('ETCUSDT_divergence_5m') < 59:
    #             redis.set(self.symbol + '_divergence_5m', -1, ex=60)
    #             redis.set(self.symbol + '_last_time_bottom_divergence_5m', self.klines_5m['date'].values[-1])
    #         return -1
    #     elif divergence_5m == 1:
    #         if redis.ttl('ETCUSDT_divergence_5m') < 59:
    #             redis.set(self.symbol + '_divergence_5m', 1, ex=60)
    #             redis.set(self.symbol + '_last_time_top_divergence_5m', self.klines_5m['date'].values[-1])
    #         return 1
    #     else:
    #         return redis.get(self.symbol + '_divergence_5m')  # 返回一分钟内背离
    #
    # def divergence_15m(self):
    #     divergence_15m = BinanceKlinesTool.divergence(self.klines_15m)
    #     if divergence_15m == -1:
    #         if redis.ttl('ETCUSDT_divergence_15m') < 59:
    #             redis.set(self.symbol + '_divergence_15m', -1, ex=60)
    #             redis.set(self.symbol + '_last_time_bottom_divergence_15m', self.klines_15m['date'].values[-1])
    #         return -1
    #     elif divergence_15m == 1:
    #         if redis.ttl('ETCUSDT_divergence_15m') < 59:
    #             redis.set(self.symbol + '_divergence_15m', 1, ex=60)
    #             redis.set(self.symbol + '_last_time_top_divergence_15m', self.klines_15m['date'].values[-1])
    #         return 1
    #     else:
    #         return redis.get(self.symbol + '_divergence_15m')  # 返回一分钟内背离
    #
    # def divergence_30m(self):
    #     divergence_30m = BinanceKlinesTool.divergence(self.klines_30m)
    #     if divergence_30m == -1:
    #         if redis.ttl('ETCUSDT_divergence_30m') < 59:
    #             redis.set(self.symbol + '_divergence_30m', -1, ex=60)
    #             redis.set(self.symbol + '_last_time_bottom_divergence_30m', self.klines_30m['date'].values[-1])
    #         return -1
    #     elif divergence_30m == 1:
    #         if redis.ttl('ETCUSDT_divergence_30m') < 59:
    #             redis.set(self.symbol + '_divergence_30m', 1, ex=60)
    #             redis.set(self.symbol + '_last_time_top_divergence_30m', self.klines_30m['date'].values[-1])
    #         return 1
    #     else:
    #         return redis.get(self.symbol + '_divergence_15m')  # 返回一分钟内背离
    #
    # def divergence_1h(self):
    #     divergence_1h = BinanceKlinesTool.divergence(self.klines_1h)
    #     if divergence_1h == -1:
    #         if redis.ttl('ETCUSDT_divergence_1h') < 59:
    #             redis.set(self.symbol + '_divergence_1h', -1, ex=60 * 15)
    #             redis.set(self.symbol + '_last_time_bottom_divergence_1h', self.klines_1h['date'].values[-1])
    #         return -1
    #     elif divergence_1h == 1:
    #         if redis.ttl('ETCUSDT_divergence_1h') < 59:
    #             redis.set(self.symbol + '_divergence_1h', 1, ex=60 * 15)
    #             redis.set(self.symbol + '_last_time_top_divergence_1h', self.klines_1h['date'].values[-1])
    #         return 1
    #     else:
    #         return redis.get(self.symbol + '_divergence_1h')  # 返回一分钟内背离
